/* 
 * File:   Rationnel.cpp
 * Author: Gab'z
 * 
 * Created on 1 mai 2012, 19:46
 */

#include "Rationnel.h"

Rationnel* Rationnel::clone() const {
    return new Rationnel(_num, _denom);
}

Rationnel::~Rationnel() {
}

std::string Rationnel::toString() const {
    // utiliser un flux de sortie pour créer la chaîne
    std::ostringstream oss;
    // écrire la valeur dans le flux
    oss << _num; // renvoyer une string
    if (_denom != 1) oss << "/" << _denom;
    return oss.str();
}

double Rationnel::value() const {
    return (double) _num / (double) _denom;
};

Rationnel& Rationnel::operator+=(const Rationnel& r) {
    _num = _num * r._denom + _denom * r._num;
    _denom = _denom * r._denom;
    simplifier();
    return *this;
}

Rationnel& Rationnel::operator-=(const Rationnel& r) {
    _num = _num * r._denom - _denom * r._num;
    _denom = _denom * r._denom;
    simplifier();
    return *this;
}

Rationnel& Rationnel::operator*=(const Rationnel& r) {
    _num = _num * r._num;
    _denom = _denom * r._denom;
    simplifier();
    return *this;
}

Rationnel& Rationnel::operator/=(const Rationnel& r) {
    _num = _num * r._denom;
    _denom = _denom * r._num;
    simplifier();
    return *this;
}

Rationnel operator+(const Rationnel& r1, const Rationnel& r2) {
    Rationnel r(r1);
    r += r2;
    return r;
}

Rationnel operator-(const Rationnel& r1, const Rationnel& r2) {
    Rationnel r(r1);
    r -= r2;
    return r;
}

Rationnel operator*(const Rationnel& r1, const Rationnel& r2) {
    Rationnel r(r1);
    r *= r2;
    return r;
}

Rationnel operator/(const Rationnel& r1, const Rationnel& r2) {
    Rationnel r(r1);
    r /= r2;
    return r;
}

// calcul du pgcd

int Rationnel::pgcd(int a, int b) const {
    if (a == 0 || b == 0) return 0;
    if (a < 0) a = -a;
    if (b < 0) b = -b;
    while (a != b) {
        if (a > b) a = a - b;
        else b = b - a;
    }
    return a;
}

// simplification de Rationnel

void Rationnel::simplifier() {
    if (_num == 0) {
        _denom = 1;
        return;
    }
    if (_denom == 0) return;
    int p = pgcd(_num, _denom);
    _num /= p;
    _denom /= p;
    if (_denom < 0) {
        _denom = -_denom;
        _num = -_num;
    }
}
